/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../mars/comm/napi/util/napi_common.h"
#include "../mars/baseevent/napi/com_ohos_mars_BaseEvent.h"
#include "../mars/sdt/napi/com_ohos_mars_sdt_SdtLogic_JS2C.h"
#include "../mars/stn/napi/com_ohos_mars_stn_StnLogic_JS2C.h"
#include "../mars/log/napi/JS2C_Xlog.h"
#include <algorithm>
EXTERN_C_START

#define LOG_DOMAIN 0x0201
#define LOG_TAG "MY_TAG"

#include "hilog/log.h"

struct NapiPropertyDescriptor {
    napi_property_descriptor* desc;
    int len;
};

napi_value AddClass(napi_env env, napi_callback_info info);

static NapiPropertyDescriptor InitBaseEvent()
{
    napi_property_descriptor desc[] = {
        DECLARE_NAPI_FUNCTION("BaseEvent_onCreate",
                              JS_com_ohos_mars_BaseEvent_onCreate),
        DECLARE_NAPI_FUNCTION("BaseEvent_onInitConfigBeforeOnCreate",
                              JS_com_ohos_mars_BaseEvent_onInitConfigBeforeOnCreate),
        DECLARE_NAPI_FUNCTION("BaseEvent_onDestroy",
                              JS_com_ohos_mars_BaseEvent_onDestroy),
        DECLARE_NAPI_FUNCTION("BaseEvent_onForeground",
                              JS_com_ohos_mars_BaseEvent_onForeground),
        DECLARE_NAPI_FUNCTION("BaseEvent_onNetworkChange",
                              JS_com_ohos_mars_BaseEvent_onNetworkChange),
        DECLARE_NAPI_FUNCTION("BaseEvent_onSingalCrash",
                              JS_com_ohos_mars_BaseEvent_onSingalCrash),
        DECLARE_NAPI_FUNCTION("BaseEvent_onExceptionCrash",
                              JS_com_ohos_mars_BaseEvent_onExceptionCrash),
        DECLARE_NAPI_FUNCTION("Alarm_onAlarm",
                              JS_com_ohos_mars_comm_Alarm_onAlarm)
    };
    int len = sizeof(desc) / sizeof(desc[0]);
    napi_property_descriptor* baseEvent =  new napi_property_descriptor[len];
    for (int i = 0; i < len; i++) {
        baseEvent[i]=desc[i];
    }
    NapiPropertyDescriptor baseEventDesc;
    baseEventDesc.desc = baseEvent;
    baseEventDesc.len = len;
    return baseEventDesc;
}


static NapiPropertyDescriptor InitSdtLogicPartOne()
{
    napi_property_descriptor desc[] = {
        DECLARE_NAPI_FUNCTION("SdtLogic_getLoadLibraries",
                              JS_com_ohos_mars_sdt_SdtLogic_getLoadLibraries),
        DECLARE_NAPI_FUNCTION("SdtLogic_setHttpNetcheckCGI",
                              JS_com_ohos_mars_sdt_SdtLogic_setHttpNetcheckCGI),
        DECLARE_NAPI_FUNCTION("StnLogic_getLoadLibraries",
                              JS_com_ohos_mars_stn_StnLogic_getLoadLibraries),
        DECLARE_NAPI_FUNCTION("StnLogic_reset",
                              JS_com_ohos_mars_stn_StnLogic_reset),
        DECLARE_NAPI_FUNCTION("StnLogic_resetAndInitEncoderVersion",
                              JS_com_ohos_mars_stn_StnLogic_resetAndInitEncoderVersion),
        DECLARE_NAPI_FUNCTION("StnLogic_setLonglinkSvrAddr",
                              JS_com_ohos_mars_stn_StnLogic_setLonglinkSvrAddr),
        DECLARE_NAPI_FUNCTION("StnLogic_setShortlinkSvrAddr",
                              JS_com_ohos_mars_stn_StnLogic_setShortlinkSvrAddr),
        DECLARE_NAPI_FUNCTION("StnLogic_setDebugIP",
                              JS_com_ohos_mars_stn_StnLogic_setDebugIP),
        DECLARE_NAPI_FUNCTION("StnLogic_setBackupIPs",
                              JS_com_ohos_mars_stn_StnLogic_setBackupIPs),
        DECLARE_NAPI_FUNCTION("StnLogic_startTask",
                              JS_com_ohos_mars_stn_StnLogic_startTask),
        DECLARE_NAPI_FUNCTION("StnLogic_stopTask",
                              JS_com_ohos_mars_stn_StnLogic_stopTask)
    };
    int len = sizeof(desc) / sizeof(desc[0]);
    napi_property_descriptor* sdtLogic =  new napi_property_descriptor[len];
    for (int i = 0; i < len; i++) {
        sdtLogic[i]=desc[i];
    }
    NapiPropertyDescriptor sdtLogicDesc;
    sdtLogicDesc.desc = sdtLogic;
    sdtLogicDesc.len = len;
    return sdtLogicDesc;
}

static NapiPropertyDescriptor InitSdtLogicPartTwo()
{
    napi_property_descriptor desc[] = {
        DECLARE_NAPI_FUNCTION("StnLogic_hasTask",
                              JS_com_ohos_mars_stn_StnLogic_hasTask),
        DECLARE_NAPI_FUNCTION("StnLogic_redoTask",
                              JS_com_ohos_mars_stn_StnLogic_redoTask),
        DECLARE_NAPI_FUNCTION("StnLogic_clearTask",
                              JS_com_ohos_mars_stn_StnLogic_clearTask),
        DECLARE_NAPI_FUNCTION("StnLogic_makesureLongLinkConnected",
                              JS_com_ohos_mars_stn_StnLogic_makesureLongLinkConnected),
        DECLARE_NAPI_FUNCTION("StnLogic_setSignallingStrategy",
                              JS_com_ohos_mars_stn_StnLogic_setSignallingStrategy),
        DECLARE_NAPI_FUNCTION("StnLogic_keepSignalling",
                              JS_com_ohos_mars_stn_StnLogic_keepSignalling),
        DECLARE_NAPI_FUNCTION("StnLogic_stopSignalling",
                              JS_com_ohos_mars_stn_StnLogic_stopSignalling),
        DECLARE_NAPI_FUNCTION("StnLogic_setClientVersion",
                              JS_com_ohos_mars_stn_StnLogic_setClientVersion),
        DECLARE_NAPI_FUNCTION("StnLogic_genTaskID",
                              JS_com_ohos_mars_stn_StnLogic_genTaskID),
        DECLARE_NAPI_FUNCTION("StnLogic_reconnectStart",
                              JS_com_ohos_mars_stn_StnLogic_reconnectStart),
        DECLARE_NAPI_FUNCTION("StnLogic_reconnectStop",
                              JS_com_ohos_mars_stn_StnLogic_reconnectStop),
        DECLARE_NAPI_FUNCTION("StnLogic_delayTask",
                              JS_com_ohos_mars_stn_StnLogic_delayTask)
    };
    int len = sizeof(desc) / sizeof(desc[0]);
    napi_property_descriptor* sdtLogic =  new napi_property_descriptor[len];
    for (int i = 0; i < len; i++) {
        sdtLogic[i]=desc[i];
    }
    NapiPropertyDescriptor sdtLogicDesc;
    sdtLogicDesc.desc = sdtLogic;
    sdtLogicDesc.len = len;
    return sdtLogicDesc;
}


static NapiPropertyDescriptor InitXlog()
{
    napi_property_descriptor desc[] = {
        DECLARE_NAPI_FUNCTION("Xlog_newXlogInstance",
                              JS_com_ohos_mars_xlog_Xlog_newXlogInstance),
        DECLARE_NAPI_FUNCTION("Xlog_getXlogInstance",
                              JS_com_ohos_mars_xlog_Xlog_getXlogInstance),
        DECLARE_NAPI_FUNCTION("Xlog_releaseXlogInstance",
                              JS_com_ohos_mars_xlog_Xlog_releaseXlogInstance),
        DECLARE_NAPI_FUNCTION("Xlog_appenderOpen",
                              JS_com_tenScent_mars_xlog_Xlog_appenderOpen),
        DECLARE_NAPI_FUNCTION("Xlog_appenderClose",
                              JS_com_ohos_mars_xlog_Xlog_appenderClose),
        DECLARE_NAPI_FUNCTION("Xlog_appenderFlush",
                              JS_com_ohos_mars_xlog_Xlog_appenderFlush),
        DECLARE_NAPI_FUNCTION("Xlog_logWrite",
                              JS_com_ohos_mars_xlog_Xlog_logWrite),
        DECLARE_NAPI_FUNCTION("Xlog_logWrite2",
                              JS_com_ohos_mars_xlog_Xlog_logWrite2),
        DECLARE_NAPI_FUNCTION("Xlog_getLogLevel",
                              JS_com_ohos_mars_xlog_Xlog_getLogLevel),
        DECLARE_NAPI_FUNCTION("Xlog_setLogLevel",
                              JS_com_ohos_mars_xlog_Xlog_setLogLevel),
        DECLARE_NAPI_FUNCTION("Xlog_setAppenderMode",
                              JS_com_ohos_mars_xlog_Xlog_setAppenderMode),
        DECLARE_NAPI_FUNCTION("Xlog_setConsoleLogOpen",
                              JS_com_ohos_mars_xlog_Xlog_setConsoleLogOpen),
        DECLARE_NAPI_FUNCTION("Xlog_setMaxFileSize",
                              JS_com_ohos_mars_xlog_Xlog_setMaxFileSize),
        DECLARE_NAPI_FUNCTION("Xlog_setMaxAliveTime",
                              JS_com_ohos_mars_xlog_Xlog_setMaxAliveTime),
        DECLARE_NAPI_FUNCTION("AddClass", AddClass),
    };
    int len = sizeof(desc) / sizeof(desc[0]);
    napi_property_descriptor* xlog =  new napi_property_descriptor[len];
    for (int i = 0; i < len; i++) {
        xlog[i]=desc[i];
    }
    NapiPropertyDescriptor xlogDesc;
    xlogDesc.desc = xlog;
    xlogDesc.len = len;
    return xlogDesc;
}


/*
 * function for module exports
 */
static napi_value Init(napi_env env, napi_value exports)
{
    NapiPropertyDescriptor baseEventPropertyDesc = InitBaseEvent();
    NapiPropertyDescriptor sdtLogicPropertyPartOneDesc = InitSdtLogicPartOne();
    NapiPropertyDescriptor sdtLogicPropertyPartTwoDesc = InitSdtLogicPartTwo();
    NapiPropertyDescriptor xlogPropertyDesc = InitXlog();
    int mergeLen = baseEventPropertyDesc.len + sdtLogicPropertyPartOneDesc.len +
        sdtLogicPropertyPartTwoDesc.len + xlogPropertyDesc.len;
    napi_property_descriptor mergeAllPropertyDesc[mergeLen];
    for (int i = 0; i < baseEventPropertyDesc.len; i++) {
        mergeAllPropertyDesc[i] =  baseEventPropertyDesc.desc[i];
    }
    for (int i = 0; i < sdtLogicPropertyPartOneDesc.len; i++) {
        mergeAllPropertyDesc[baseEventPropertyDesc.len+i] =  sdtLogicPropertyPartOneDesc.desc[i];
    }
    for (int i = 0; i < sdtLogicPropertyPartTwoDesc.len; i++) {
        mergeAllPropertyDesc[baseEventPropertyDesc.len
                             +sdtLogicPropertyPartOneDesc.len+i] =  sdtLogicPropertyPartTwoDesc.desc[i];
    }
    for (int i = 0; i < xlogPropertyDesc.len; i++) {
        mergeAllPropertyDesc[baseEventPropertyDesc.len
                             +sdtLogicPropertyPartOneDesc.len
                             +sdtLogicPropertyPartTwoDesc.len+i] =  xlogPropertyDesc.desc[i];
    }
    NAPI_CALL(env, napi_define_properties(env, exports, mergeLen, mergeAllPropertyDesc));
    return exports;
}
EXTERN_C_END

/*
 * Module define
 */
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "marsnapi",
.nm_priv = ((void*)0),
.reserved = { 0 },
};

/*
 * Module register function
 */
extern "C" __attribute__((constructor)) void RegisterModule(void)
{
napi_module_register(&demoModule);
}
